<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
abstract class DMAbstractView {

	/**
	 * @var Array of DMTemplateHelper objects
	 */
	private static $default_helpers = array();

	/**
	 * @var Array of DMTemplateHelper objects
	 */
	private static $extension_helpers = array();

	/**
	 * @var Array of DMTemplateHelper objects
	 */
	private static $module_helpers = array();

	/**
	 * @var DMTemplateHelper
	 */
	protected $helper;

	/**
	 * @var DMSession
	 */
	protected $session;

	/**
	 * @param DMSession session
	 */
	public function __construct(DMSession $session) {
		$this->setSession($session);
	}

	private function populateArrayWithPath(&$array, $path) {
		$array = array();
		$it = new RecursiveDirectoryIterator($path);
		foreach (new RecursiveIteratorIterator($it) as $filename) {
			$pathname = realpath($filename);
			// skip hidden folders, such as .svn
			if (strpos($pathname, "/.") !== false) {
				continue;
			}
			if (strlen(basename($pathname)) < 3) {
				continue;
			}
			if (substr($pathname, -4, 4) != ".php") {
				continue;
			}

			$info = pathinfo($pathname);
			if (array_key_exists("extension", $info)) {
				$class = basename($pathname, "." . $info['extension']);
				if (interface_exists($class)) {
					continue;
				}

				include_once($pathname);
				$rclass = new ReflectionClass($class);
				if ($rclass->isSubclassOf("DMCustomTemplateHelper")) {
					$class = new $class($this, $this->getSession());
					$array[] = $class;
				}
			}
		}
	}

	/**
	 * @return array Array of instances of all registered DMTemplateHelpers.
	 * @since 2.0
	 * @see getModuleHelpers()
	 * @see getDefaultHelpers()
	 * @see getExtensionHelpers()
	 */
	public function getAllHelpers() {
		return array_merge($this->getDefaultHelpers(),
						   $this->getModuleHelpers(),
						   $this->getExtensionHelpers());
	}

	/**
	 * @return array Array of instances of all registered custom
	 * DMTemplateHelpers.
	 * @since 2.0
	 * @see getDefaultHelpers()
	 * @see getAllHelpers()
	 * @see getModuleHelpers()
	 */
	public function getExtensionHelpers() {
		if (count(self::$extension_helpers) < 1) {
			$this->populateArrayWithPath(self::$extension_helpers,
					realpath(dirname(__FILE__) . "/../../extensions/helpers"));
		}
		return self::$extension_helpers;
	}

	/**
	 * @return array Array of instances of all default DMTemplateHelpers.
	 * @since 2.0
	 * @see getAllHelpers()
	 * @see getCustomHelpers()
	 */
	public function getDefaultHelpers() {
		if (count(self::$default_helpers) < 1) {
			$this->populateArrayWithPath(self::$default_helpers,
					realpath(dirname(__FILE__) . "/../template"));
		}
		return self::$default_helpers;
	}

	/**
	 * @return DMTemplateHelper
	 * @since 2.0
	 */
	public function getHelper() {
		return $this->helper;
	}

	/**
	 * @param DMTemplateHelper helper
	 */
	protected function setHelper(DMTemplateHelper $helper) {
		$this->helper = $helper;
	}

	/**
	 * Returns the server processing time in microseconds. To use this method,
	 * call it at the very end of a page template.
	 *
	 * @return float
	 * @since 0.1
	 */
	public function getLoadTime() {
		global $dmloadstart;
		return microtime(true) - $dmloadstart;
	}

	/**
	 * @return array Array of instances of all DMTemplateHelpers provided by
	 * registered and enabled modules.
	 * @since 2.0
	 * @see getDefaultHelpers()
	 * @see getAllHelpers()
	 * @see getExtensionHelpers()
	 */
	public function getModuleHelpers() {
		if (count(self::$module_helpers) < 1) {
			$dmm = DMModuleManager::getInstance();
			foreach ($dmm->getEnabledModules() as $module) {
				if ($module instanceof DMBridgeTemplateHelperModule) {
					self::$module_helpers[] = $module->getTemplateHelper($this,
							$this->getSession());
				}
			}
		}
		return self::$module_helpers;
	}

	/**
	 * @return DMSession
	 * @since 2.0
	 */
	public function getSession() {
		return $this->session;
	}

	/**
	 * @param DMSession session
	 */
	public function setSession(DMSession $session) {
		$this->session = $session;
	}

}
